#ifndef _WX_HTMLLBOX_H_
#define _WX_HTMLLBOX_H_

#include "wx/vlbox.h"               // base class
#include "wx/html/htmlwin.h"
#include "wx/ctrlsub.h"
#include "wx/filesys.h"

class wxHtmlCell;
class wxHtmlWinParser;
class wxHtmlListBoxCache;
class wxHtmlListBoxStyle;

extern const wxChar wxHtmlListBoxNameStr[];
extern const wxChar wxSimpleHtmlListBoxNameStr[];

class wxHtmlListBox : public wxVListBox,
  public wxHtmlWindowInterface,
  public wxHtmlWindowMouseHelper {
    DECLARE_ABSTRACT_CLASS( wxHtmlListBox )
  public:
    // constructors and such
    // ---------------------

    // default constructor, you must call Create() later
    wxHtmlListBox();

    // normal constructor which calls Create() internally
    wxHtmlListBox( wxWindow *parent,
                   wxWindowID id = wxID_ANY,
                   const wxPoint& pos = wxDefaultPosition,
                   const wxSize& size = wxDefaultSize,
                   long style = 0,
                   const wxString& name = wxHtmlListBoxNameStr );

    bool Create( wxWindow *parent,
                 wxWindowID id = wxID_ANY,
                 const wxPoint& pos = wxDefaultPosition,
                 const wxSize& size = wxDefaultSize,
                 long style = 0,
                 const wxString& name = wxHtmlListBoxNameStr );

    // destructor cleans up whatever resources we use
    virtual ~wxHtmlListBox();

    // override some base class virtuals
    virtual void RefreshLine( size_t line );
    virtual void RefreshLines( size_t from, size_t to );
    virtual void RefreshAll();
    virtual void SetItemCount( size_t count );

    // retrieve the file system used by the wxHtmlWinParser: if you use
    // relative paths in your HTML, you should use its ChangePathTo() method
    wxFileSystem& GetFileSystem() { return m_filesystem; }
    const wxFileSystem& GetFileSystem() const { return m_filesystem; }

    virtual void OnInternalIdle();

  protected:
    virtual wxString OnGetItem( size_t n ) const = 0;
    virtual wxString OnGetItemMarkup( size_t n ) const;
    virtual wxColour GetSelectedTextColour( const wxColour& colFg ) const;
    virtual wxColour GetSelectedTextBgColour( const wxColour& colBg ) const;
    virtual void OnDrawItem( wxDC& dc, const wxRect& rect, size_t n ) const;
    virtual wxCoord OnMeasureItem( size_t n ) const;
    virtual void OnLinkClicked( size_t n, const wxHtmlLinkInfo& link );
    void OnSize( wxSizeEvent& event );
    void OnMouseMove( wxMouseEvent& event );
    void OnLeftDown( wxMouseEvent& event );
    void Init();
    void CacheItem( size_t n ) const;
  private:
    virtual void SetHTMLWindowTitle( const wxString& title );
    virtual void OnHTMLLinkClicked( const wxHtmlLinkInfo& link );
    virtual wxHtmlOpeningStatus OnHTMLOpeningURL( wxHtmlURLType type, const wxString& url, wxString *redirect ) const;
    virtual wxPoint HTMLCoordsToWindow( wxHtmlCell *cell, const wxPoint& pos ) const;
    virtual wxWindow* GetHTMLWindow();
    virtual wxColour GetHTMLBackgroundColour() const;
    virtual void SetHTMLBackgroundColour( const wxColour& clr );
    virtual void SetHTMLBackgroundImage( const wxBitmap& bmpBg );
    virtual void SetHTMLStatusText( const wxString& text );
    virtual wxCursor GetHTMLCursor( HTMLCursor type ) const;
    size_t GetItemForCell( const wxHtmlCell *cell ) const;
    wxPoint GetRootCellCoords( size_t n ) const;
    bool PhysicalCoordsToCell( wxPoint& pos, wxHtmlCell*& cell ) const;
    wxPoint CellCoordsToPhysical( const wxPoint& pos, wxHtmlCell *cell ) const;
  private:
    wxHtmlListBoxCache *m_cache;
    wxHtmlWinParser *m_htmlParser;
    wxFileSystem m_filesystem;
    wxHtmlListBoxStyle *m_htmlRendStyle;
    friend class wxHtmlListBoxStyle;
    friend class wxHtmlListBoxWinInterface;
    DECLARE_EVENT_TABLE()
    DECLARE_NO_COPY_CLASS( wxHtmlListBox )
};

#define wxHLB_DEFAULT_STYLE     wxBORDER_SUNKEN
#define wxHLB_MULTIPLE          wxLB_MULTIPLE

class wxSimpleHtmlListBox : public wxHtmlListBox,
  public wxItemContainer {
  public:
    wxSimpleHtmlListBox() { }
    wxSimpleHtmlListBox( wxWindow *parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition,
                         const wxSize& size = wxDefaultSize, int n = 0, const wxString choices[] = NULL,
                         long style = wxHLB_DEFAULT_STYLE, const wxValidator& validator = wxDefaultValidator,
                         const wxString& name = wxSimpleHtmlListBoxNameStr ) {
      Create( parent, id, pos, size, n, choices, style, validator, name );
    }

    wxSimpleHtmlListBox( wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
                         const wxArrayString& choices, long style = wxHLB_DEFAULT_STYLE,
                         const wxValidator& validator = wxDefaultValidator,
                         const wxString& name = wxSimpleHtmlListBoxNameStr ) {
      Create( parent, id, pos, size, choices, style, validator, name );
    }

    bool Create( wxWindow *parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
                 int n = 0, const wxString choices[] = NULL, long style = wxHLB_DEFAULT_STYLE,
                 const wxValidator& validator = wxDefaultValidator,
                 const wxString& name = wxSimpleHtmlListBoxNameStr );
    bool Create( wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, const wxArrayString& choices,
                 long style = wxHLB_DEFAULT_STYLE, const wxValidator& validator = wxDefaultValidator,
                 const wxString& name = wxSimpleHtmlListBoxNameStr );

    virtual ~wxSimpleHtmlListBox();
    void SetSelection( int n ) { wxVListBox::SetSelection( n ); }
    int GetSelection() const { return wxVListBox::GetSelection(); }
    wxCONTROL_ITEMCONTAINER_CLIENTDATAOBJECT_RECAST
    virtual unsigned int GetCount() const { return m_items.GetCount(); }
    virtual wxString GetString( unsigned int n ) const;
    wxArrayString GetStrings() const { return m_items; }
    virtual void SetString( unsigned int n, const wxString& s );
    virtual void Clear();
    virtual void Delete( unsigned int n );
    void Append( const wxArrayString& strings );
    int Append( const wxString& item ) { return wxItemContainer::Append( item ); }
    int Append( const wxString& item, void *clientData ) { return wxItemContainer::Append( item, clientData ); }
    int Append( const wxString& item, wxClientData *clientData ) { return wxItemContainer::Append( item, clientData ); }
  protected:
    virtual int DoAppend( const wxString& item );
    virtual int DoInsert( const wxString& item, unsigned int pos );
    virtual void DoSetItemClientData( unsigned int n, void *clientData ) { m_HTMLclientData[n] = clientData; }
    virtual void *DoGetItemClientData( unsigned int n ) const { return m_HTMLclientData[n]; }
    virtual void DoSetItemClientObject( unsigned int n, wxClientData *clientData ) {
      m_HTMLclientData[n] = ( void * )clientData;
    }
    virtual wxClientData *DoGetItemClientObject( unsigned int n ) const { return ( wxClientData * )m_HTMLclientData[n]; }
    void UpdateCount();
    virtual void SetItemCount( size_t count ) { wxHtmlListBox::SetItemCount( count ); }
    virtual void SetLineCount( size_t count ) { wxHtmlListBox::SetLineCount( count ); }
    virtual wxString OnGetItem( size_t n ) const { return m_items[n]; }
    wxArrayString   m_items;
    wxArrayPtrVoid  m_HTMLclientData;
    DECLARE_NO_COPY_CLASS( wxSimpleHtmlListBox )
};

#endif // _WX_HTMLLBOX_H_

